<template>
  <!-- 拨打电话弹框 -->
  <div :class="'dial-number-wrap dialog-wrap ' +($Ctl.isCs(1)?'gradation-bg':'bg')">
    <div class="dialog-title">
      {{ state == 1 ? '正在与' : '呼叫'}}<span class="cell-username">{{ calledUserName }}</span><span v-show="state == 1">{{ cellType == 1 ? '语音' : '视频' }}</span>
    </div>
    <!-- 通话屏幕 -->
    <div class="cell-screen">
      <!-- 呼叫中 -->
      <div class="celling" v-show="connectState == 0">
        <p class="celling-desc">正在与对方连接{{cellType == 1 ? '语音' : '视频'}}<span class="ani_dot">...</span></p>
        <div class="celling-pic">
          <img v-if="cellType == 2" :src="parames.headUrl || defaultUserHead">
          <i v-else class="iconfont icon_yuyin"></i>
        </div>
      </div>
      <div class="success-cell" v-show="connectState == 1">
        <!-- 视频通话中 -->
        <div class="videoing" v-show="cellType == 2">
          <div id="remote_video" style="height: 100%;width: 100%;"></div>
          <!-- 自己的视频 -->
          <div id="self_rong_video" class="self-video">
            <video autoplay playsinline height="100px" width="140px"></video>
          </div>
        </div>
        <!-- 语音通话中 -->
        <div class="voiceing" v-show="cellType == 1">
          <ul class="left-ripple ripple-wrap">
            <li class="ripple-item ripple-one"></li>
            <li class="ripple-item ripple-two"></li>
            <li class="ripple-item ripple-three"></li>
          </ul>
          <div class="iconfont icon_yuyin"></div>
          <ul class="right-ripple ripple-wrap">
            <li class="ripple-item ripple-three"></li>
            <li class="ripple-item ripple-two"></li>
            <li class="ripple-item ripple-one"></li>
          </ul>
        </div>
        <!-- 时间统计 -->
        <div class="timing">{{ connectingTime }}</div>
      </div>
    </div>
    <!-- 底部按钮 -->
    <div class="cell-bottom-btns">
      <div class="cell-btn">
        <el-tooltip :disabled="resolutionList.length == 0" v-model="showResolutionType" :popper-class="'resolution-type'" effect="dark" placement="top">
          <div slot="content">
            <ul class="resolution-type-list">
              <li v-for="(item, i) in resolutionList" :key="i" @click="changeResolution(item)">{{ item.width + '*' + item.height }}</li>
            </ul>
          </div>
          <i class="cell-btn-icon change-cellType-btn resolution-text">
            <span>{{ currentResolution.width }}</span>
            <span>*</span>
            <span>{{ currentResolution.height }}</span>
          </i>
        </el-tooltip>
        <p class="cell-btn-text">分辨率</p>
      </div>
      <div :class="`cell-btn${videoFlag?' cannot-click':''}`" @click="startVideotape">
        <i class="cell-btn-icon el-icon-video-camera-solid change-cellType-btn"></i>
        <p class="cell-btn-text">录像</p>
      </div>
      <div class="cell-btn" @click="changeCellType(false)">
        <i class="cell-btn-icon iconfont change-cellType-btn" :class="{'iconweibiaoti-_shipin': cellType == 1, 'icon_yuyin': cellType == 2}"></i>
        <p class="cell-btn-text">切换为{{ cellType == 1 ? '视频' : '语音' }}</p>
      </div>
      <div class="cell-btn" @click="closeFun">
        <i class="cell-btn-icon iconfont icon_guaduan end-cell-btn"></i>
        <p class="cell-btn-text">结束</p>
      </div>
    </div>
  </div>
</template>
<script>
  import { getAliRTCToken, callUser } from '@/api/api'
  import { setInterval, setTimeout } from 'timers'

  require('../../../../public/static/plugins/aliyun-webrtc-sdk-1.10.1.min.js')

  var hour = '00' // 时
  var minus = '00' // 分
  var seconds = '00' // 秒
  var x=0,a=0,b=0; // 计时器定义的变量

  // 阿里RTC对象
  var aliWebrtc = null;

  export default {
    props: {
      parames: {
        default () {
          return {}
        }
      }
    },
    data () {
      return {
        defaultUserHead: require('../../../assets/images/default/userHead.png'),
        state: 0, // 状态 0-呼叫中  1-通话中
        cellType: 2, // 呼叫方式 1-语音 2-视频
        userName: this.$store.state.userInfo.name || '', // 发起呼叫的用户
        calledUserName: this.parames.name || '', // 被呼叫的用户名称
        connectState: 0, // 连通话接状态 0-未连接  1-连接成功
        connectingTime: '00:00:00', // 连接时间计时
        roomId: this.$store.state.userInfo.accountName + '_' + this.parames.accountName + '_' + new Date().getTime(), //'90909090' 房间号：用户名+时间戳
        joinedUer: {},
        resolutionList: [], // 分辨率
        currentResolution: {
          width: 640,
          height: 480
        }, // 当前分辨率
        showResolutionType: false,
        videoFlag: false //是否正在录像
      }
    },
    created () {
      let that = this
      
      /* 上次未断开，先断开 */
      if(aliWebrtc) {
        console.log("上次未断开，先断开");
        aliWebrtc.leaveChannel();
        aliWebrtc.dispose();
        aliWebrtc = null
      }
      /**
       * AliWebRTC isSupport检测
       */ 
      AliRtcEngine.isSupport().then(re => {
        console.log(re);
        that.initAliRtc();
      }).catch(err => {
        that.$Ctl.message(err.message, 'warning')
        console.log("不支持阿里云服务：" + err.message);
        that.$emit('close')
      })

      that.$nextTick(() => {
        that.$Ctl.loading(0)
      })

      window.FunList.changeCellType= that.changeCellType
    },
    methods: {
      // 切换通信方式
      changeCellType(paramType) {
        let that = this
        let localVideo = $('#self_rong_video video');
        that.$Ctl.loading(1, 1000);
        if(!paramType || paramType != that.cellType) {
          if(paramType == 2 || that.cellType == 1) {
            // 发布本地相机流
            aliWebrtc.configLocalCameraPublish = true
            // 本地预览开启
            aliWebrtc.startPreview(localVideo[0]).then((obj) => {
              console.log('开启本地预览')
            }).catch((error) => { 
              console.log(error.message); 
            });
            // 恢复本地视频采集
            aliWebrtc.muteLocalCamera(true);
            console.log('恢复本地视频采集');
            // 切换为视频
            that.cellType = 2
          } else {
            // 取消发布本地相机流
            aliWebrtc.configLocalCameraPublish = false
            // 本地预览关闭
            aliWebrtc.stopPreview(localVideo[0]).then((obj) => {
              console.log('关闭本地预览')
            }).catch((error) => { 
              console.log(error.message); 
            });
            // 停止本地视频采集
            aliWebrtc.muteLocalCamera(false);
            console.log('停止本地视频采集');
            // 切换为语音
            that.cellType = 1
          }
          aliWebrtc.publish().then((res) => {
            console.log('发起者重新发布流成功');
          }, (error) => {
            console.log(error.message);
          });
        }
      },
      // 开始计时
      startTiming() {
        let that = this
        // 参数初始化
        x=0
        a=0
        b=0
        if(window.t1) {
          clearInterval(window.t1._id)
          window.t1 = null
        }

        window.t1 = setInterval(() => {
          that.runTime()
        }, 1000)
      },
      // 计时器算法
      runTime() {
        let that = this
        x++
        if(x<10){
          seconds = '0' + x;
        }else if(x >= 10 && x <= 59){
          seconds = x;
        }else if(x > 59){
          seconds = '00';
          x = 0;
          a++;
        }

        if(a < 10){
          minus = '0' + a;
        }else if(a >= 10 && a <= 59){
          minus = a;
        }else if(a > 59){
          minus = '00';
          a = 0;
          b++;
        }

        if(b<10){
          hour = '0' + b;
        }else if(b >=10 && b <= 59){
          hour = b;
        }

        that.connectingTime = hour+":"+minus+":"+seconds;
      },
      // 发起者关闭
      closeFun() {
        console.log('发起者关闭')
        this.leaveRoom(() => {
          this.$emit('close')
        })
      },
      // 初始化通信参数
      initCellParames() {
        let that = this
        that.state = 0 // 状态 0-呼叫中  1-通话中
        that.cellType = 2 // 呼叫方式 1-语音 2-视频
        that.calledUserName = '' // 呼叫的用户名称
        that.connectState = 0 // 连通话接状态 0-未连接  1-连接成功
        that.connectingTime = '00:00:00' // 连接时间计时
      },
      initialization(userId) {
        if (aliWebrtc) {
          aliWebrtc.configRemoteAudio(userId, false);
          aliWebrtc.configRemoteCameraTrack(userId, false, false);
        }
      },
      // 通知服务端发起通话
      cellNotice() {
        let that = this
        let param = {
          account: that.$store.state.userInfo.accountName || '', // 发起人
          targetUserAccount: that.parames.accountName || '', // 目标用户
          roomId: that.roomId	// 房间号
        }
        callUser(param).then(res => {
          if(res.status === 200) {
            console.log('通知服务端通话成功！')
          }
        })
      },
      /**
       * 初始化阿里RTC服务
       * 1、实例化
       * 2、设置监听回调
       * 3、发起者先加入房间
       */ 
      initAliRtc() {
        let that = this
        aliWebrtc = new AliRtcEngine("");
        /**
         * 获取设备信息，返回摄像头和音频输入设备
         */ 
        aliWebrtc.getDevices().then((res)=>{
          console.log(aliWebrtc.currentCamera)
          if(res && res.videoDevices && res.videoDevices.length > 0) {
            // 获取可支持的分辨率
            aliWebrtc.getAvailableResolutions(res.videoDevices[0].deviceId).then((re)=>{
              that.resolutionList = re
            }).catch((error)=>{ 
              console.log(error.message)
            });
          }
          
        }).catch((error)=>{ 
          console.log(error.message)
        });
        /**
         * remote用户加入房间 onJoin
         */ 
        aliWebrtc.on('onJoin', (publisher) => {
          if(publisher.userId){
            // aliWebrtc.getUserList()
            that.joinedUer = publisher
            console.log('remote用户加入房间')
          }
        });
        /**
         * remote流发布事件 onPublish
         * 订阅音视频流
         */
        aliWebrtc.on('onPublisher', (publisher) => {
          console.log('remote用户发布资源');
          that.initialization(publisher.userId)

          // 订阅资源
          that.receivePublishManual(publisher).then(res => {
            if(that.state == 0 && that.connectState == 0) {
              // 首次通话，建立remote流的页面展示
              that.creatDomAndshowRemoteVideo(publisher)
              // 将人员位置信息传送给控制台定位方法
              let positionInfo = publisher.displayName
              let personInfo = that.parames
              that.$Ctl.locateCallee(positionInfo, personInfo)
            }
            if(res.hasVideo) {
              // 切换为视频模式
              that.changeCellType(2)
            } else {
              // 切换为音频模式
              that.changeCellType(1)
            }
            console.log('订阅remote发布资源成功')
            // 修改连接状态并开始计时
            if(that.state == 0 && that.connectState == 0) {
              that.startTiming()
              that.state = 1
              that.connectState = 1
            }
          });
        });

        /**
         * remote流结束发布事件 onUnPublisher
         * 初始化订阅状态
         * 关闭弹框
         */ 
        aliWebrtc.on('onUnPublisher', (publisher) => {
          console.log('remote取消发布视频流');
          // 判断取消发布的是什么流
          // aliWebrtc.configRemoteCameraTrack(publisher.userId, true, false);
          // 切换为语音模式
          // that.changeCellType(2);
          // removeDom(publisher.userId);
          // that.initialization(publisher.userId);
        });
        
        /**
         *  错误信息
         */ 
        aliWebrtc.on('onError', (error) => {
          console.warn('error',error);
          var msg = error && error.message ? error.message : error;
          if (msg && msg.indexOf('no session') > -1) {
              msg = "请重新登录：" + msg;
          }
          if (msg && msg.indexOf('screen share error') > -1) {
              msg = "屏幕共享已取消";
          }

          if(error.code == 15) {
              msg = "没有开启H5兼容";
          }
          if(error.type === "publish") {
              console.log("推流断开 需要停止推流");
              $(".push-stream").click();
          }
          if(error.type === "subscribe") {
              console.log("订阅断开 取消订阅该userId的所有订阅并移除所有该userId的dom")
              aliWebrtc.unSubscribe(error.userId).then(re => {
                  console.log("订阅断开 取消订阅成功");
              }).catch(err => console.log("订阅断开 取消订阅失败", err))
              that.removeDom(error.userId);
          }
          console.log(msg);
        });

        /**
         * 检测到用户离开频道
         * 移除用户视图
         * 关闭弹框
         */ 
        aliWebrtc.on('onLeave', (publisher) => {
          console.log('检测到用户离开频道')
          that.initialization(publisher.userId);
          that.removeDom(publisher.userId);
          that.closeFun()
        })
        // 当前用户先加入房间
        that.joinroom()
      },
      /**
       * 加入房间
       * 默认开启预览
       * 获取鉴权信息
       * 加入房间
       * 本地默认自动推视频流（视频流 + 音频流）
       * 发布本地流
       */ 
      joinroom() {
        let that = this
        //1.预览
        let localVideo = $('#self_rong_video video');
        aliWebrtc.startPreview(localVideo[0]).then((obj) => {
          console.log('开启本地预览')
        }).catch((error) => { 
          console.log(error.message); 
        });
        //2. 获取频道鉴权令牌参数 -->
        getAliRTCToken({
          channelID: that.roomId,
          user: that.$store.state.userInfo.accountName
        }).then((res) => {
          if(res.status === 200) {
            let authInfo = res.data
            authInfo.gslb = authInfo.gslb.split(',')
            authInfo.channel = that.roomId

            //3. 加入房间 默认推音频视频流
            aliWebrtc.joinChannel(authInfo, that.userName).then(() => {
              console.log('发起者加入频道成功');
              // 4. 发布本地流
              aliWebrtc.configLocalAudioPublish = true;
              aliWebrtc.configLocalCameraPublish = true;
              aliWebrtc.publish().then((res) => {
                console.log('发起者发布流成功');
                // 调用后端接口，通知被呼叫者
                that.cellNotice()
              }, (error) => {
                console.log(error.message);
              });
            }).catch((error) => {
              console.log(error.message);
            })
          }
        }).catch((error) => {
          console.log(error.message);
        });
      },
      /**
       * 获取dom标签 设置video
       */ 
      creatDomAndshowRemoteVideo(v) {
        var dom = this.getDisplayRemoteVideo(v.userId)

        aliWebrtc.setDisplayRemoteVideo(v.userId, dom, 1);
      },
      /**
       * 创建获取订阅的remote的video标签
       */ 
      getDisplayRemoteVideo(userId) {
        var videoWrapper = $('#remote_video');

        videoWrapper.append($('<video id="' + userId + '_video_screen" autoplay playsinline style="height: 100%;width: 100%;"></video>'))
        return videoWrapper.find('video')[0];
      },
      /**
       * 移除dom
       */ 
      removeDom(userId) {
        if(userId) {
          $("#" + userId + "_video_screen").remove();
        }
      },
      /**
       * 订阅设置
       * 是否订阅远端音频流
       * 是否订阅远端相机流
       * 订阅远程发布流
       */
      receivePublishManual(v) {
        return new Promise((resolve, reject) => {
          console.log("开始订阅remote用户资源流");

          let streamConfigs = v.streamConfigs // 远程流内容
          let hasAudio = false // 是否含有可用音频流
          let hasVideo = false // 是否含有可用视频流
          for(let i=0, len=streamConfigs.length; i < len; i++) {
            console.log('remote用户发布的资源流 ' + (i+1) + '、type=' + streamConfigs[i].type + '; state=' + streamConfigs[i].state);
            if(streamConfigs[i].type === 'audio' && streamConfigs[i].state === 'active') {
              hasAudio = true
              console.log('订阅了remote用户音频资源流')
            } else if(streamConfigs[i].type === 'video' && streamConfigs[i].state === 'active' ) {
              hasVideo = true
              console.log('订阅了remote用户视频资源流')
            }
          }
          // 音频流设置 && 视频流设置
          aliWebrtc.configRemoteAudio(v.userId, hasAudio);
          aliWebrtc.configRemoteCameraTrack(v.userId, true, hasVideo);
          // 订阅远程发布流
          aliWebrtc.subscribe(v.userId).then(re => {
            resolve({
              'hasAudio': hasAudio,
              'hasVideo': hasVideo
            });
          }).catch((err) => {
            reject(err);
            console.log(err.message);
          });
        })
      },
      /**
       * 挂断
       */ 
      leaveRoom(callback) {
        window.topVue.$Cs.openRecordingScreen(1)
        if(aliWebrtc){
          aliWebrtc.stopPreview().then(()=>{
            console.log('取消本地预览成功')
            aliWebrtc.muteLocalCamera(true)
            console.log('停止视频采集')
            aliWebrtc.muteLocalMic(true)
            console.log('停止音频采集')
            aliWebrtc.leaveChannel();
            aliWebrtc.dispose();
            aliWebrtc = null;
            // 初始化通讯参数
            this.initCellParames()
            console.log('发起者离开频道')
            callback && callback()
          }).catch((error) => {
            console.log('取消本地预览失败')
          });
        }
      },
      // 更改分辨率
      changeResolution(obj) {
        let that = this

        if(obj.width !== that.currentResolution.width && obj.height !== that.currentResolution.width) {
          let localVideo = $('#self_rong_video video');
          that.showResolutionType = false
          // 调整分辨率
          aliWebrtc.videoProfile = { 
            width: obj.width,
            height: obj.height
          };
          // 重新开启本地预览
          aliWebrtc.startPreview(localVideo[0]).then((obj) => {
            console.log('重新开启本地预览')
          }).catch((error) => { 
            console.log(error.message); 
          });
          // 重新发布资源
          aliWebrtc.publish().then((res) => {
            console.log('发起者重新发布流成功');
            that.currentResolution = {...obj}
            that.$Ctl.message('分辨率切换成功！', 'success')
          }, (error) => {
            console.log(error.message);
          });
        } else {
          that.$Ctl.message('分辨率选择错误！', 'warning')
        }
      },
      // 开始录像
      startVideotape() {
        !this.videoFlag && window.topVue.$Cs.openRecordingScreen(0)
        this.videoFlag = true
      }
    },
    beforeDestroy() {
      this.leaveRoom()
    }
  }
</script>

<style lang="scss">
  .dial-number-wrap {
    .cell-username {
      padding: 0 10px;
    }
    .cell-screen {
      margin-top: 25px;
      width: 100%;
      height: 62%;
      background: #000;
      .celling {
        padding-top: 50px;
        height: 100%;
        text-align: center;
        .celling-desc {
          color: #4095F0;
          font-size: 16px;
          .ani_dot {
            margin-left: 6px;
            display: inline-block;
            width: 1.5em;
            letter-spacing: 0.4em;
            vertical-align: bottom;
            overflow: hidden;
            animation: dot 3s infinite step-start;
          }
        }
        .celling-pic {
          margin-top: 20px;
          i {
            color: #3e3d3d;
            font-size: 80px;
          }
          img {
            width: 90px;
            height: 90px;
          }
        }
      }
      .success-cell {
        position: relative;
        width: 100%;
        height: 100%;
        .videoing {
          width: 100%;
          height: 100%;
          .rong-video {
            width: 100%;
            height: 100%;
            video {
              width: 100%;
              height: 100%;
            }
          }
          .self-video {
            position: absolute;
            top: 0;
            right: 0;
            height: 100px;
            width: 140px;
          }
        }
        .voiceing {
          display: flex;
          padding-top: 40px;
          justify-content: center;
          height: 100%;
          color: #258EF5;
          text-align: center;
          .ripple-wrap {
            display: flex;
            margin-top: 35px;
            width: 70px;
            height: 50px;
            justify-content: space-between;
            align-items: center;
            list-style: none;
            .ripple-item {
              width: 8px;
              height: 50px;
              background: #1a4e81;
            }
            .ripple-one {
              animation: ripple 1s ease-in-out 0s infinite;
            }
            .ripple-two {
              animation: ripple 1s ease-in-out .4s infinite;
            }
            .ripple-three {
              animation: ripple 1s ease-in-out .8s infinite;
            }
          }
          .iconfont {
            font-size: 100px;
          }
        }
        .timing {
          position: absolute;
          top: 70%;
          left: 0;
          width: 100%;
          margin-top: 30px;
          color: #258EF5;
          text-align: center;
        }
      }
    }
    .cell-bottom-btns {
      margin-top: 15px;
      display: flex;
      justify-content: center;
      width: 100%;
      .cell-btn {
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 200px;
        cursor: pointer;
        &.cannot-click{
          cursor: not-allowed;
        }
        .cell-btn-icon {
          display: block;
          width: 54px;
          height: 54px;
          line-height: 46px;
          text-align: center;
          border-radius: 50%;
          font-size: 26px;
          color: #FFF;
          &.change-cellType-btn {
            border: 4px solid rgba(63,132,199,.3);
            background:rgba(63,132,199,1);
            background-clip: padding-box;
          }
          &.end-cell-btn {
            border: 4px solid rgba(151,59,53,.3);
            background:rgba(151,59,53,1);
            background-clip: padding-box;
          }
          &.resolution-text {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            line-height: 12px;
          }
        }
        .cell-btn-text {
          margin-top: 6px;
          font-size: 14px;
          color:rgba(255,255,255,1);
        }
      }
    }
  }
  .resolution-type {
    .resolution-type-list {
      li {
        height: 20px;
        line-height: 20px;
        font-size: 14px;
        cursor: pointer;
        &:hover {
          color: #1583fe;
        }
      }
    }
  }
</style>


